package org.f0rb.core.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Class com.oliveoffice.demo.common description goes here.
 *
 * @author Yuan Zhen
 * @version 1.0.0 11-11-7
 */
public abstract class DefaultWebServiceImpl<T extends WebModel<?>> implements WebService<T> {
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultWebServiceImpl.class);

    /**
     * TODO 改进：不直接返回结果，而是让业务实现根据自己的需要返回对应的结果
     * {@inheritDoc}
     */
    @Override
    public String execute(final T o) {
        LOGGER.debug("execute [{}:{}] start;", new Object[]{o.model(), o.service()});

        String convertedServiceName = convertServiceName(o.service());
        String serviceResult = WebServiceResult.CODE_404.alias;

        try {
            serviceResult = execute((convertedServiceName), o);
            return serviceResult;
        } catch (RuntimeException re) {
            re.printStackTrace();
			o.addMessage(re.getMessage());
			return isJsonService(convertedServiceName) ?
					WebServiceResult.JSON.alias : WebServiceResult.CODE_500.alias;
        }
        finally {
            LOGGER.debug("execute service [{}:{}] end with result [{}]!",
                    new Object[]{o.model(), o.service(), serviceResult});
        }
    }

    /**
     * Web业务请求处理.
     *
     * @param serviceName 经过{@code convertServiceName(String)}处理过的业务名称
     * @param o           {@link WebModel}的子类
     * @return a result String to decide which view is displayed
     */
    protected abstract String execute(String serviceName, T o);

    /**
     * 转换serviceName的格式.
     * <p/>
     * 将{@code serviceName}全部转为大写，并且将短横线(-)转为下划线(_)，
     * 以方便调用{@link org.f0rb.demo.model.user.UserServiceName#valueOf(String)}
     * 例如 "check-username" -> "CHECK_USERNAME"
     * </p>
     * PS: 使用短横线方便做SEO
     *
     * @param serviceName serviceName
     * @return 大写加下划线组合的字符串
     * @see org.f0rb.demo.model.user.UserServiceName
     */
    public static String convertServiceName(final String serviceName) {
        return serviceName.toUpperCase().replaceAll("-", "_");
    }

    private static final String JSON_SERVICE_SYMBOL = "0";

    /**
     * 判断访问的业务是否返回JSON视图.
     *
     * @param serviceName serviceName
     * @return true if serviceName is in the jsonService list; otherwise false
     */
    protected final boolean isJsonService(String serviceName) {
        return serviceName.endsWith(JSON_SERVICE_SYMBOL);
    }
}
